package com.wetool.service;

import com.wetool.entity.PLUCode;
import com.wetool.exception.CommodityNotFindException;
import com.wetool.exception.MerchantNotLoginException;
import com.wetool.exception.PLUSaveException;
import com.wetool.jpa.PLUCodeRepo;
import com.wetool.model.CommodityModify;
import com.wetool.model.PLUModelModify;
import com.wetool.model.PluModel;
import com.wetool.utils.ArrayAlgorithmUtil;
import com.wetool.utils.ArrayToStringUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.persistence.Transient;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * PLU码业务处理
 * @author lixin
 */
@Service
public class PLUService {
	
	private static final Logger logger = LogManager.getLogger(PLUService.class);
	
	@Autowired
	private PLUCodeRepo pLUCodeRepo;
	
	@Autowired
	private CommodityService commodityService;
	
	@Autowired
	private ArrayAlgorithmUtil arrayAlgorithmUtil;
	
	/**
	 * 查询PLU码并初始化生成最小PLU
	 * @param merchantId
	 * @return
	 * @throws Exception
	 */
	public String getMinPLUCode(Long shopId,Long merchantId) throws Exception{
		if (shopId == null) {
			logger.debug("PLU码业务处理(查询PLU码并初始化生成最小PLU) -> 商家ID为空");
			throw new MerchantNotLoginException("PLU码业务处理(查询PLU码并初始化生成最小PLU) -> 商家ID为空");
		}
		PLUCode pLUCode = pLUCodeRepo.getByShopId(shopId);
		if (pLUCode == null || StringUtils.isEmpty(pLUCode.getArrayString())) {
			/* 商家没有添加PLU码初始化添加数据库中 */
			String arrayToString = ArrayToStringUtil.encode(new Long[100][10] );
			save(shopId,arrayToString);
			return "0001";
		}
		/* 获取商家PLU 二维数组矩阵 */
		Long[][] arrays = ArrayToStringUtil.decode(pLUCode.getArrayString());
		String PLU = arrayAlgorithmUtil.getMin(arrays,merchantId); //查询二维数组为空最小下标返回;;
		logger.debug("PLU码业务处理(查询PLU码并初始化生成最小PLU) . 参数 商家ID【{}】 最小PLU 【{}】",shopId, PLU);
		return PLU;
	}
	
	/**
	 * 传秤展示列表
	 * @param shopId
	 * @param size
	 * @return
	 * @throws Exception
	 */
	@Transient
	public List<PluModel> list(Long shopId, Long size) throws Exception {
		PLUCode pLUCode = pLUCodeRepo.getByShopId(shopId);
		List<PluModel> pluModels = null;
		if (pLUCode == null || StringUtils.isEmpty(pLUCode.getArrayString())) {
			/* 商家没有添加PLU码初始化添加数据库中 */
			Long[][] array = new Long[100][10];
			String arrayToString = ArrayToStringUtil.encode(array);
			save(shopId,arrayToString);
			/* 遍历数据列表 */
			pluModels = getPluModels(array,size);
			return pluModels;
		}
		String arryString = pLUCode.getArrayString();
		Long[][] array = ArrayToStringUtil.decode(arryString);
		pluModels = getPluModels(array,size);
		return pluModels;
	}
	
	/**
	 * 二维数组固定下标生成对应称重商品PLU码
	 * @param subscript PLU码
	 * @param arrayString 数组反序列化字符串
	 * @return String 数组序列化后字符串
	 * @throws Exception
	 */
	@Transient
	public  String add( Long shopId,PLUModelModify pLUModelModify) throws Exception{
		PLUCode pLUCode = pLUCodeRepo.getByShopId(shopId);
		if (shopId == null) {
			logger.debug("PLU码业务处理(二维数组固定下标生成对应称重商品PLU码) -> 商家ID为空");
			throw new MerchantNotLoginException("PLU码业务处理(二维数组固定下标生成对应称重商品PLU码) -> 商家ID为空");
		}
		String arrayString = pLUCode.getArrayString();
		String yString = pLUModelModify.getHotKey().replaceAll(".(?=.)","");//取个位数
		String xString = pLUModelModify.getHotKey().substring(0, pLUModelModify.getHotKey().length() -1);//取百十位数
		if (xString == null || "".equals(xString)) {
			xString = "0";
		}
		int x = Integer.parseInt(xString);//字符串转int
		int y = Integer.parseInt(yString);//字符串转int
		Long[][] arrays = ArrayToStringUtil.decode(arrayString);//数组反序列化
		logger.debug("PLU码业务处理(二维数组固定下标生成对应称重商品PLU码) . 参数  二维数组节点 【{}】",arrays[x][y]);
		arrays[x][y] = pLUModelModify.getCommodityId();// 数组中设置称重商品ID
		arrayString  = ArrayToStringUtil.encode(arrays);//数组序列化
		pLUCode = save(pLUCode.getId(),shopId,arrayString);
		if (pLUCode == null) {
			logger.debug("PLU码业务处理(二维数组固定下标生成对应称重商品PLU码) PLU保存失败 ");
			throw new PLUSaveException("PLU码业务处理(二维数组固定下标生成对应称重商品PLU码) PLU保存失败 ");
		}
        return  arrayString;
	}
	
	/**
	 * 二维数组固定下标元素删除商品ID
	 * @param subscript PLU码
	 * @param arrayString 数组反序列化字符串
	 * @return String 数组序列化后字符串
	 * @throws Exception
	 */
	public String deleteDate(Long shopId,String subscript) throws Exception{
		PLUCode pLUCode = pLUCodeRepo.getByShopId(shopId);
		if (pLUCode == null) {
			logger.debug("PLU码业务处理(二维数组固定下标元素删除商品ID) -> 商家ID为空");
			throw new MerchantNotLoginException("PLU码业务处理(二维数组固定下标元素删除商品ID) -> 商家ID为空");
		}
		String arrayString = pLUCode.getArrayString();
		String yString = subscript.replaceAll(".(?=.)","");//取个位数
        String xString = subscript.substring(0, subscript.length() -1);//取百十位数
        int x = Integer.parseInt(xString);//字符串转int
        int y = Integer.parseInt(yString);//字符串转int
        Long[][] arrays = ArrayToStringUtil.decode(arrayString);//数组反序列化
		arrays[x][y] = null;//数组元素设置为null
		arrayString = ArrayToStringUtil.encode(arrays); //数组序列化
		pLUCode = save(pLUCode.getId(),shopId, arrayString);
		if (pLUCode == null) {
			logger.debug("PLU码业务处理(二维数组固定下标元素删除商品ID) PLU保存失败 ");
			throw new PLUSaveException("PLU码业务处理(二维数组固定下标元素删除商品ID) PLU保存失败 ");
		}
		return arrayString;
	}
	
	/**
	 * 修改PLU码并保存DB
	 * @param id PLU码实体ID
	 * @param merchantId 商家ID
	 * @param arrayString 二维数组序列化字符串
	 * @return PLUCode plu实体
	 */
	public PLUCode save(Long id ,Long merchantId,String arrayString){
		PLUCode p = new PLUCode();
		p.setId(id);
		p.setShopId(merchantId);
		p.setArrayString(arrayString);
		return pLUCodeRepo.save(p);
	}

	/**
	 * 保存PLU码并保存DB
	 * @param merchantId 商家ID
	 * @param arrayString 二维数组序列化字符串
	 * @return PLUCode plu实体
	 */
	public PLUCode save(Long merchantId,String arrayString){
		PLUCode p = new PLUCode();
		p.setShopId(merchantId);
		p.setArrayString(arrayString);
		return pLUCodeRepo.saveAndFlush(p);
	}
	
	
	public List<PluModel> getPluModels(Long[][] array , Long size) throws CommodityNotFindException{
		String yString = size.toString().replaceAll(".(?=.)","");//取个位数
		String xString = size.toString().substring(0, size.toString().length() -1);//取百十位数
		int x = Integer.parseInt(xString);//字符串转int
		int y = Integer.parseInt(yString);//字符串转int
		List<PluModel> pluModels = new ArrayList<>();
		for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array[i].length; j++) {
            	if (i == 0 && j == 0) {
            		continue;
            	}
            	CommodityModify co = commodityService.getById(array[i][j]);
            	PluModel pluModel = new PluModel();
            	if (co != null) {
            		pluModel.setCommodityId(co.getId());
            		pluModel.setPLU(String.format("%04d", i*10 +j));
            		pluModel.setPLU(co.getBarcode());
            		pluModel.setName(co.getName());
            		pluModel.setPrice((co.getSellingPrice()==null)? "0.00":co.getSellingPrice()
            				.setScale(2,BigDecimal.ROUND_HALF_UP).toString());
            	}
            	pluModel.setHotKey(i*10+j);
            	pluModels.add(pluModel);
            	if (i == x && j == y) {
            		return pluModels;
            	}
            	}
        }
		return pluModels;
	}

}
